<template>
  <div class="emplyee-container">
    <!-- <ul>
      <li><router-link to="/params/foo/bar">/params/foo/bar</router-link></li>
      <li><router-link to="/optional-params">/optional-params</router-link></li>
      <li><router-link to="/optional-params/foo">/optional-params/foo</router-link></li>
      <li><router-link to="/params-with-regex/123">/params-with-regex/123</router-link></li>
      <li><router-link to="/params-with-regex/abc">/params-with-regex/abc</router-link></li>
      <li><router-link to="/asterisk/foo">/asterisk/foo</router-link></li>
      <li><router-link to="/asterisk/foo/bar">/asterisk/foo/bar</router-link></li>
      <li><router-link to="/optional-group/bar">/optional-group/bar</router-link></li>
      <li><router-link to="/optional-group/foo/bar">/optional-group/foo/bar</router-link></li>
    </ul> -->
    <div class="left">
      <el-input
        v-model="pageParams.keyword"
        placeholder="请输入内容"
        prefix-icon="el-icon-search"
        @input="inputTmp"
      />
      <!-- 树形组件的位置，等一下去组织页面c过来 -->
      <el-tree
        ref="treeRef"
        show-checkbox
        node-key="id"
        :data="treeList"
        :props="defaultProps"
        :expand-on-click-node="false"
        highlight-current
        @current-change="currentChange"
      />
    </div>
    <div class="right">
      <div class="r-top">
        <el-button size="mini" type="primary" @click="$router.push('/employee/detail')">添加员工</el-button>
        <el-button size="mini" @click="importOpen = true">excel导入</el-button>
        <el-button size="mini" @click="userExportTmp">excel导出</el-button>
      </div>
      <div class="r-middle">
        <!-- 表格按字段排序 分 前端排序 和 后端排队（发请求，sortable设置为custom） -->
        <!-- https://juejin.cn/post/7039145366524002317  别人真实的需求 -->
        <el-table
          :data="tableData"
          style="width: 100%"
          :default-sort="{prop: 'mobile', order: 'descending'}"
        >
          <el-table-column
            prop="staffPhoto"
            label="头像"
          >
            <template slot-scope="{row}">
              <img v-if="row.staffPhoto" class="staff-photo" :src="row.staffPhoto" alt="图片没有的时候显示的文字">
              <!-- 常见的假值  0 '' false null undefined -->
              <!-- console.log(11 && 22 && 0) 逻辑与  前面为真就往后走，遇到假值就停止 -->
              <!-- console.log(11 || 22 || 0) 逻辑或  前面为真就停止 -->
              <span v-else class="staff-photo-text">{{ row.username && row.username.charAt(0) }}</span>
              <!-- <span v-else>{{ row.username?.charAt(0) }}</span> -->
              <!-- 逻辑中断 + 可选链 -->
            </template>
          </el-table-column>
          <el-table-column
            prop="username"
            label="姓名"
          />
          <el-table-column
            prop="mobile"
            label="手机号"
            sortable
          />
          <el-table-column
            prop="workNumber"
            label="工号"
            :sortable="true"
          />
          <el-table-column
            prop="formOfEmployment"
            label="聘用形式"
          >
            <span slot-scope="{row}">{{ row.formOfEmployment == 1 ? '正式': '非正式' }}</span>
          </el-table-column>
          <el-table-column
            prop="departmentName"
            label="部门"
          />
          <el-table-column
            prop="timeOfEntry"
            label="入职时间"
            sortable
          />
          <el-table-column
            label="操作"
            width="180"
          >
            <template v-slot="{row}">
              <el-button type="text" @click="$router.push(`/employee/detail/${row.id}`)">查看</el-button>
              <el-button type="text" :loading="row.isLoading" @click="assignRolesTmp(row)">角色</el-button>
              <el-popconfirm
                title="确定要删除这个员工吗？"
                style="margin-left: 5px"
                @onConfirm="deleteEmployeeTmp(row.id)"
              >
                <el-button slot="reference" type="text">删除</el-button>
              </el-popconfirm>
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div class="r-bottom">
        <!-- 属性 page-sizes page-size 两个不一样，一个是数组，一个是数值 -->
        <el-pagination
          layout="total, prev, pager, next"
          :total="total"
          :page-size="pageParams.pagesize"
          :current-page="pageParams.page"
          @current-change="handleCurrentChange"
        />
      </div>
    </div>

    <!-- v-model  sync -->
    <ImportExcelCom :dialog-visible.sync="importOpen" @import-success="getEmployee" />
    <!-- 下面使用el-upload 二次封装的上传组件 -->
    <!-- <ImportExcelTwo v-model="importOpen" /> -->
    <!-- <ImportExcelTwo :value="importOpen" @input="importOpen = $event" /> -->
    <!-- 父子组件的生命周期函数顺序： -->

    <el-dialog
      title="提示"
      :visible.sync="dialogRoleVisible"
    >
      <el-checkbox-group v-model="checkList">
        <!-- 官网的代码能够用label就可以选中，是因为之前的数组数据，是这个样子 ['选中且禁用','复选框 A'] -->
        <el-checkbox v-for="item in roleList" :key="item.id" :label="item.id">{{ item.name }}</el-checkbox>
      </el-checkbox-group>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogRoleVisible = false">取 消</el-button>
        <el-button type="primary" @click="submitAssignRoleTmp">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import { getDepartmentRequest } from '@/api/department'
import { transfromListToTree } from '@/utils'
import { getEmployeeRequest, userExportRequest, deleteEmployeeRequest, getEnabledRoleListRequest, assignRolesRequest, getEmployeeInfoByIdRequest } from '@/api/employee'
import _ from 'lodash-es'
// import FileSaver from 'file-saver'
import { saveAs } from 'file-saver'
import ImportExcelCom from './components/importExcel.vue'
import ImportExcelTwo from './components/importExcelTwo.vue'

// yarn add lodash-es
// lodash-es   ---- tree-shaking 摇树
// lodash 100个函数  引入了1个， 打包的时候， 还是会引入100个函数
// _.cloneDeep
// _.debounce()

// 幽林依赖 --- 一个包在package.json里面没有下载，但是我们在代码里面可以直接import 使用
// 就是因为下载的包，又有package.json 又会依赖其他的包，
// console.log(1111, _)
// _.debounce(fn, 100)

let currentGlobalId = null

export default {
  name: 'EmployeeCom',
  components: { ImportExcelCom, ImportExcelTwo },
  // props: {
  //   list: {
  //     type: Array,
  //     default: () => []
  //   }
  // },
  // data: {
  //   a: 1
  // },
  data() {
    return {
      tableData: [],
      treeList: [],
      defaultProps: {
        children: 'children',
        label: 'name'
      },
      // 后面发请求需要的一些参数，一般包在一个对象里面，不要写散了
      pageParams: {
        page: 1,
        pagesize: 3,
        keyword: '',
        // departmentId要么就传具体的值，要么就不写这个字段
        // 如果写了这个字段，又传递空字符串，请求就会报错
        departmentId: ''
      },
      total: 0,
      importOpen: false,
      // 下面三个变量是 分配就是弹出框的变量
      dialogRoleVisible: false,
      checkList: [],
      roleList: [],
      currentId: null,
      roleLoading: false
    }
  },
  created() {
    // 谷歌：vue里面 函数使用 防抖
    this.inputTmp = _.debounce(this.inputTmp, 500)
    this.getDepartment()
    // this.getEmployee()
    this.getEnabledRoleList()
  },
  beforeDestroy() {
    this.inputTmp.cancel()
  },
  methods: {
    async getDepartment() {
      const res = await getDepartmentRequest()
      // 下面data数据，是给el-tree组件使用的 树形结构
      // 下面这句话，是将treeList数据更新，然后就会触发dom更新，但是dom更新是异步的
      this.treeList = transfromListToTree(res.data, 0)
      this.pageParams.departmentId = this.treeList[0].id

      this.getEmployee()

      // 下面代码就是等dom更新以后，再去设置dom的一些变化
      this.$nextTick(() => {
        this.$refs.treeRef.setCurrentKey(this.pageParams.departmentId)
      })
    },
    async getEmployee() {
      const res = await getEmployeeRequest(this.pageParams)
      this.tableData = res.data.rows
      this.total = res.data.total
      this.tableData.forEach(item => {
        this.$set(item, 'isLoading', false)
      })
    },
    currentChange(a, b) {
      console.log(a, b)
      this.pageParams.departmentId = a.id

      this.getEmployee()
    },
    handleCurrentChange(val) {
      // 页面上视图页码值发生了改变，赋值给js里面的变量
      this.pageParams.page = val
      this.getEmployee()
    },
    inputTmp() {
      this.getEmployee()
    },
    async userExportTmp() {
      const res = await userExportRequest()
      // 将二进制保存为一个文件
      saveAs(res, '员工表.xlsx')
    },
    async deleteEmployeeTmp(id) {
      await deleteEmployeeRequest(id)
      // 有个bug: 当前页面如果只有一条数据，删除以后，应该把页码值返回到上一页，不然请求当前页面就没有数据。 还需要注意，请求不能有负值的页面，还需要做大于0的处理
      if (this.tableData.length === 1 && this.pageParams.page > 1) {
        this.pageParams.page--
      }
      // 删除完毕以后，还需要刷新页面
      this.getEmployee()
    },
    async getEnabledRoleList() {
      const res = await getEnabledRoleListRequest()
      console.log(res.data)
      this.roleList = res.data
    },
    async assignRolesTmp(row) {
      // this.roleLoading = true
      try {
        row.isLoading = true
        // currentId 如果绑定到this上面，那么就会自动指向vue双向数据绑定的那一套，会将这个数据
        // 通过Object.defineProperty影响性能，因为这个数据 并不会在template模板上面使用，不需要双向绑定
        //  并不是所有的vue组件的数据，都要绑定到data上面去的
        // this.currentId = id
        currentGlobalId = row.id
        // 发请求，获取这个用户，默认有哪些权限，弹出框打开之前自动给它勾选上
        const res = await getEmployeeInfoByIdRequest(row.id)
        this.checkList = res.data.roleIds
        this.dialogRoleVisible = true
      } catch (error) {
        //
      } finally {
        // this.roleLoading = false
        // eslint-disable-next-line require-atomic-updates
        row.isLoading = false
      }
    },
    async submitAssignRoleTmp() {
      this.dialogRoleVisible = false

      await assignRolesRequest({
        // id: this.currentId,
        id: currentGlobalId,
        roleIds: this.checkList
      })
    }
    // fn: function() {

    // },
    // https://juejin.cn/post/7034458741990752287
    // 当你组件复用的使用，多个防抖直接就会冲突有bug
    // data问什么必须是一个函数返回一个对象。 props里面的数组和对象 默认值问什么必须是 函数返回一个新对象或者数组。 原因是一样的。 不能像下面这么使用
  // inputTmp2: _.debounce(function() {
  //   this.getEmployee()
  // }, 1000)
  }
}
</script>

<style lang="scss" scoped>
.emplyee-container {
  padding: 20px;
  display: flex;
  .left {
    padding: 20px;
    // background-color: lightcoral;
    flex: 0 1 280px;
  }
  .right {
    padding: 20px;
    // background-color: lightblue;
    flex: 1;
    .r-top {
      text-align: right;
    }
  }
  .r-middle {
    margin: 15px 0;
  }
  .r-bottom {
    text-align: right;
  }
  .staff-photo {
    width: 40px;
    height: 40px;
  }
  .staff-photo-text {
    width: 40px;
    height: 40px;
    display: inline-block;
    background-color: lightblue;
    border-radius: 50%;
    text-align: center;
    line-height: 40px;
    font-size: 18px;
    color: #13820b;
  }
}
</style>
